package cn.iot.sys.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.iot.common.dto.ResultMsg;
import cn.iot.sys.dao.*;
import cn.iot.sys.entity.*;
import cn.iot.sys.service.SysPoliticalService;
import cn.iot.sys.service.SysStudentService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.netsdk.demo.module.GateModule;
import com.netsdk.demo.module.LoginModule;
import com.netsdk.lib.ToolKits;
import com.sun.jna.Memory;
import io.swagger.models.auth.In;
import net.coobird.thumbnailator.Thumbnails;
import net.lingala.zip4j.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.poi.hpsf.Thumbnail;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class SysStudentServiceImpl implements SysStudentService {
    private static final String UPLOAD_DIR = "upload";
    @Resource
    private SysStudentDao sysStudentDao;
    @Resource
    private SysBedDao sysBedDao;
    @Resource
    private SysPoliticalDao sysPoliticalDao;
    @Resource
    private SysClassDao sysClassDao;
    @Resource
    private SysDocumentDao sysDocumentDao;

    private Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    public ResultMsg getSysStudentList(Map<String,Object> params) {
        logger.info("SysStudentServiceImpl getSysStudentList params{}",params);
        int pageSize = Integer.parseInt(String.valueOf(params.get("pageSize")));
        int pageNum = Integer.parseInt(String.valueOf(params.get("pageNum")));
        int start = (pageNum-1)*pageSize;
        params.remove("pageSize");
        params.put("pageSize",pageSize);
        params.put("start",start);
        List<SysStudent> sysStudentList = sysStudentDao.getSysStudentList(params);
        int count = sysStudentDao.getSysStudentListCount(params);
        int pageCount;
        if (count>0){
            pageCount = count%pageSize==0? count/pageSize:count/pageSize+1;
        }else {
            pageCount = 0;
        }
        params.put("sysStudentList",sysStudentList);
        params.put("pageCount",pageCount);
        ResultMsg msg = new ResultMsg(200,"成功",params);
        return msg;
    }

    @Transactional
    @Override
    public ResultMsg addStudent(MultipartFile file,Map<String, Object> map) {
        logger.info("SysStudentServiceImpl addStudent map{}",map);
        ResultMsg msg;
        try {
            if (file!= null &&!file.isEmpty()){
                String fileName = System.currentTimeMillis()+"_"+ file.getOriginalFilename();
                Path uploadDirPath = Paths.get(UPLOAD_DIR);
                if (!Files.exists(uploadDirPath)) {
                    try {
                        Files.createDirectories(uploadDirPath);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                Path filePath = Paths.get(UPLOAD_DIR,fileName);
                if(file.getSize()> 100 * 1024){
                    File tempFile = new File(fileName);
                    Thumbnails.of(file.getInputStream())
                            .size(700, 700)
                            .outputQuality(0.8)
                            .toFile(tempFile);

                    if (tempFile.length()>100*1024){
                        tempFile.delete();
                        return new ResultMsg(500,"照片大小需要小于100kb,请重新上传照片",null);
                    }
                    Files.move(tempFile.toPath(),filePath);
                }else {
                    Files.copy(file.getInputStream(),filePath);
                }
                map.put("photo",fileName);
            }
            int count = sysStudentDao.addStudent(map);
            if (count>0){
                msg = new ResultMsg(200,"成功",null);
                return msg;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        msg = new ResultMsg(500,"失败",null);
        return msg;
    }

    @Override
    public ResultMsg getSysStudentById(int id) {
        logger.info("SysStudentServiceImpl getSysStudentById id{}",id);
        SysStudent sysStudent = sysStudentDao.getSysStudentById(id);
        ResultMsg msg = new ResultMsg(200,"成功",sysStudent);
        return msg;
    }

    @Override
    public ResultMsg getSysStudentByStuName(String studentName) {
        logger.info("SysStudentServiceImpl getSysStudentByStuName studentName{}",studentName);
        SysStudent sysStudent = sysStudentDao.getSysStudentByStuName(studentName);
        ResultMsg msg = new ResultMsg(200,"成功",sysStudent);
        return msg;
    }

    @Override
    public ResultMsg updSysStudentById(MultipartFile file,Map<String, Object> map) {
        logger.info("SysStudentServiceImpl updSysStudentById map{}",map);
        ResultMsg msg;
        try {
            if (file!= null &&!file.isEmpty()){
                String fileName = System.currentTimeMillis()+"_"+ file.getOriginalFilename();
                Path uploadDirPath = Paths.get(UPLOAD_DIR);
                if (!Files.exists(uploadDirPath)) {
                    try {
                        Files.createDirectories(uploadDirPath);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                Path filePath = Paths.get(UPLOAD_DIR,fileName);
                if(file.getSize()> 100 * 1024){
                    File tempFile = new File(fileName);
                    Thumbnails.of(file.getInputStream())
                            .size(700, 700)
                            .outputQuality(0.8)
                            .toFile(tempFile);

                    if (tempFile.length()>100*1024){
                        tempFile.delete();
                        return new ResultMsg(500,"照片大小需要小于100kb,请重新上传照片",null);
                    }
                    Files.move(tempFile.toPath(),filePath);
                }else {
                    Files.copy(file.getInputStream(),filePath);
                }
                map.put("photo",fileName);
            }
            int count = sysStudentDao.updSysStudentById(map);
            if (count>0){
                msg = new ResultMsg(200,"成功",null);
                return msg;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        msg = new ResultMsg(500,"失败",null);
        return msg;
    }

    @Transactional
    @Override
    public ResultMsg updHostelIdByStuId(Map<String, Object> map) {
        logger.info("SysStudentServiceImpl updDormitoryIdByStuId map{}",map);
        int count = sysStudentDao.updHostelIdByStuId(map);
        ResultMsg msg;
        if (count>0){
            int num = sysBedDao.updIsOccupyById(map);
            try {
                if (num>0){
                    msg = new ResultMsg(200,"成功",null);
                    return msg;
                }
                int i = 9/0;
            } catch (Exception e) {
                throw new RuntimeException("异常回滚",e);
            }
        }
        msg = new ResultMsg(500,"失败",null);
        return msg;
    }

    @Transactional
    @Override
    public ResultMsg delById(Map<String,Object> map) {
        logger.info("SysStudentServiceImpl delById map{}",map);
        int id = Integer.parseInt((String) map.get("id"));
        String studentId = (String) map.get("studentId");
        int count = sysStudentDao.delById(id);
        ResultMsg msg;
        if (count>0){
            int num = sysBedDao.delIsOccupyBystuId(studentId);
            try {
                if (num>0){
                    msg = new ResultMsg(200,"成功",null);
                    return msg;
                }
                int i = 9/0;
            } catch (Exception e) {
                throw new RuntimeException("异常回滚",e);
            }
        }
        msg = new ResultMsg(500,"失败",null);
        return msg;
    }

    @Override
    public ResultMsg uploadStudentInfo(MultipartFile file) {
        List<SysStudent> studentInfoList = new ArrayList<>();
        List<String> errorMessages = new ArrayList<>();

        try (InputStream inputStream = file.getInputStream()) {
            Workbook workbook = new XSSFWorkbook(inputStream);
            Sheet sheet = workbook.getSheetAt(0);

            for (int i = 2; i <= sheet.getLastRowNum(); i++) { // 从第2行开始，跳过表头
                Row row = sheet.getRow(i);
                if (row != null) {
                    // 创建学生信息对象
                    SysStudent sysStudent = new SysStudent();

                    String studentName="";
                    Cell cell = row.getCell(0);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        studentName = cell.getStringCellValue();
                    }
                    String formerName="";
                    cell = row.getCell(1);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        formerName = cell.getStringCellValue();
                    }
                    String phoneNumber="";
                    cell = row.getCell(2);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        phoneNumber = cell.getStringCellValue();
                    }
                    String nativePlace="";
                    cell = row.getCell(3);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        nativePlace = cell.getStringCellValue();
                    }
                    String sex="";
                    cell = row.getCell(4);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        sex = cell.getStringCellValue();
                    }
                    String nation="";
                    cell = row.getCell(5);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        nation = cell.getStringCellValue();
                    }
                    String politicalName="";
                    cell = row.getCell(6);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        politicalName = cell.getStringCellValue();
                    }
                    String className="";
                    cell = row.getCell(7);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        className = cell.getStringCellValue();
                    }
                    String oldGraduationSchool="";
                    cell = row.getCell(8);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        oldGraduationSchool = cell.getStringCellValue();
                    }
                    Date enrollmentDate = null;
                    cell = row.getCell(9);
                    if (cell !=null) {
                        String dateStr = cell.getStringCellValue();
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                        enrollmentDate = sdf.parse(dateStr);
                    }

                    String documentName="";
                    cell = row.getCell(10);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        documentName = cell.getStringCellValue();
                    }
                    String documentNumber="";
                    cell = row.getCell(11);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        documentNumber = cell.getStringCellValue();
                    }

                    String address="";
                    cell = row.getCell(12);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        address = cell.getStringCellValue();
                    }
                    String postalCode="";
                    cell = row.getCell(13);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        postalCode = cell.getStringCellValue();
                    }

                    String homePhone="";
                    cell = row.getCell(14);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        homePhone = cell.getStringCellValue();
                    }
                    String hobby="";
                    cell = row.getCell(15);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        hobby = cell.getStringCellValue();
                    }
                    String awardSituation="";
                    cell = row.getCell(16);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        awardSituation = cell.getStringCellValue();
                    }
                    String guardianName="";
                    cell = row.getCell(17);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        guardianName = cell.getStringCellValue();
                    }
                    String relation="";
                    cell = row.getCell(18);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        relation = cell.getStringCellValue();
                    }
                    String guardianPhone="";
                    cell = row.getCell(19);
                    if (cell!= null && !CellType.BLANK.equals(cell.getCellType())) {
                        guardianPhone = cell.getStringCellValue();
                    }
                    //校验姓名
                    if (!StrUtil.isNotEmpty(studentName)){
                        errorMessages.add("第 " + (i + 1) + " 行的姓名 '" + studentName + "' 不符合！");
                        continue;
                    }
                    //校验手机号是否正确
                    String regex = "^1[3-9]\\d{9}$";
                    Pattern pattern = Pattern.compile(regex);
                    Matcher matcher = pattern.matcher(phoneNumber);
                    if(matcher.matches() == false || !StrUtil.isNotEmpty(phoneNumber)){
                        errorMessages.add("第 " + (i + 1) + " 行的手机号 '" + phoneNumber + "' 不符合！");
                        continue;
                    }
                    if (!StrUtil.isNotEmpty(homePhone)){
                        matcher = pattern.matcher(homePhone);
                        if(matcher.matches() == false || !StrUtil.isNotEmpty(homePhone)){
                            errorMessages.add("第 " + (i + 1) + " 行的家庭电话 '" + homePhone + "' 不符合！");
                            continue;
                        }
                    }
                    matcher = pattern.matcher(guardianPhone);
                    if(matcher.matches() == false || !StrUtil.isNotEmpty(guardianPhone)){
                        errorMessages.add("第 " + (i + 1) + " 行的监护人联系电话 '" + guardianPhone + "' 不符合！");
                        continue;
                    }

                    //校验政治面貌
                    if (StrUtil.isNotEmpty(politicalName)) {
                        SysPolitical sysPoliticalByName = sysPoliticalDao.getSysPoliticalByName(politicalName);
                        if (sysPoliticalByName != null) {
                            int politcalId = sysPoliticalByName.getId();
                            sysStudent.setPoliticalId(politcalId);
                        }else {
                            errorMessages.add("第 " + (i + 1) + " 行的政治面貌 '" + politicalName + "' 不符合！");
                            continue;
                        }
                    }
                    //校验班级
                    if (StrUtil.isNotEmpty(className)) {

                        SysClass sysClassByName = sysClassDao.getSysClassByName(className);
                        if (sysClassByName != null) {
                            int classId = sysClassByName.getId();
                            sysStudent.setClassId(classId);
                        }else {
                            errorMessages.add("第 " + (i + 1) + " 行的班级名称 '" + politicalName + "' 不符合！");
                            continue;
                        }
                    }
                    //证件校验
                    if (StrUtil.isNotEmpty(documentName)){
                        SysDocument sysDocumentByName = sysDocumentDao.getSysDocumentByName(documentName);
                        if (sysDocumentByName == null){
                            errorMessages.add("第 " + (i + 1) + " 行的证件类型名称 '" + documentName + "' 不符合！");
                            continue;
                        }
                        sysStudent.setDocumentId(sysDocumentByName.getId());
                        if ("居民身份证".equals(sysDocumentByName.getDocumentName())){
                            if (documentNumber.length() == 18 || documentNumber.length() == 15){
                                sysStudent.setDocumentNumber(documentNumber);
                            }else {
                                errorMessages.add("第 " + (i + 1) + " 行的证件号 '" + documentNumber + "' 不符合！");
                                continue;
                            }
                        }
                    }
                    int sexId = 0;
                    if (StrUtil.isNotEmpty(sex)){
                        if ("男".equals(sex)){
                            sexId= 1;
                        }else {
                            sexId = 2;
                        }
                        sysStudent.setSex(sexId);
                    }


                    Random random = new Random();
                    int randomNumber = random.nextInt(900000) + 100000;
                    String studentId = "YY" + randomNumber;
                    sysStudent.setStudentId(studentId);
                    sysStudent.setStudentName(studentName);
                    sysStudent.setFormerName(formerName);
                    sysStudent.setPhoneNumber(phoneNumber);
                    sysStudent.setNativePlace(nativePlace);
                    sysStudent.setNation(nation);
                    sysStudent.setOldGraduationSchool(oldGraduationSchool);
                    sysStudent.setAddress(address);
                    sysStudent.setPostalCode(postalCode);
                    sysStudent.setHomePhone(homePhone);
                    sysStudent.setGuardianPhone(guardianPhone);
                    sysStudent.setPaymentCollection("1");
                    sysStudent.setTotalAmount((float)0);
                    sysStudent.setEnrollmentDate(enrollmentDate);
                    sysStudent.setHobby(hobby);
                    studentInfoList.add(sysStudent);
                }
            }

            // 如果有错误，返回错误信息
            if (!errorMessages.isEmpty()) {
                return new ResultMsg(400, "部分数据有误，请检查并修改。", errorMessages);
            }

            // 如果所有数据都正确，保存班级信息到数据库
            for (SysStudent sysStudent : studentInfoList) {
                sysStudentDao.addStu(sysStudent);
            }

            return new ResultMsg(200, "文件上传并处理成功。", null);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResultMsg(500, "文件上传失败。", null);
        }
        catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ResultMsg deriveStuInfo() {
        logger.info("SysStudentServiceImpl deriveStuInfo start ...");
        try {
            // 创建工作簿
            Workbook workbook = new XSSFWorkbook();
            // 创建工作表
            Sheet sheet = workbook.createSheet("学生信息");

            // 标题行
            Row headerRow = sheet.createRow(0);
            Cell idHeader = headerRow.createCell(0);
            idHeader.setCellValue("学号");
            Cell nameHeader = headerRow.createCell(1);
            nameHeader.setCellValue("姓名");
            Cell phoneHeader = headerRow.createCell(2);
            phoneHeader.setCellValue("电话");
            Cell classHeader = headerRow.createCell(3);
            classHeader.setCellValue("班级名称");
            Cell parentHeader = headerRow.createCell(4);
            parentHeader.setCellValue("家长电话");

            // 模拟从数据库获取数据
            List<SysStudent> list = sysStudentDao.getStudentAll();

            for (int i = 0; i < list.size(); i++) {
                Row dataRow = sheet.createRow(i + 1);
                Cell idCell = dataRow.createCell(0);
                idCell.setCellValue(list.get(i).getStudentId());
                Cell nameCell = dataRow.createCell(1);
                nameCell.setCellValue(list.get(i).getStudentName());
                Cell phoneCell = dataRow.createCell(2);
                phoneCell.setCellValue(list.get(i).getPhoneNumber());
                Cell classCell = dataRow.createCell(3);
                classCell.setCellValue(list.get(i).getClassName());
                Cell parentCell = dataRow.createCell(4);
                parentCell.setCellValue(list.get(i).getGuardianPhone());
            }

            // 写入文件
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
            String timeStamp = sdf.format(new Date());
            String fileName = System.getProperty("user.home") + "/Desktop/学生信息" + timeStamp + ".xlsx";
            try (FileOutputStream fos = new FileOutputStream(fileName)) {
                workbook.write(fos);
            }
            return new ResultMsg(200,"桌面生成Excel表成功（学生信息"+timeStamp+".xlsx）",null);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResultMsg(500,"Excel表生成失败",null);
        }
    }

    @Override
    public ResultMsg getStudentAll() {
        logger.info("SysStudentServiceImpl deriveStuInfo start ...");
        List<SysStudent> sysStudentList = sysStudentDao.getStudentAll();
        ResultMsg msg = new ResultMsg(200,"成功",sysStudentList);
        return msg;
    }

    @Override
    public ResultMsg getStuListByClassId(int classId) {
        logger.info("SysStudentServiceImpl getStuListByClassId classId{}",classId);
        QueryWrapper<SysStudent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("classId",classId);
        List<SysStudent> sysStudentList = sysStudentDao.selectList(queryWrapper);
        ResultMsg msg = new ResultMsg(200,"成功",sysStudentList);
        return msg;
    }

    @Override
    public ResultMsg uploadStudentPicture(MultipartFile file) {
        // 保存解压后的学生信息和照片错误信息
        List<String> errorMessages = new ArrayList<>();

        try (InputStream inputStream = file.getInputStream()) {
            // 使用 Apache Commons Compress 解压缩 ZIP 文件
            File zipFile = new File("/tmp/" + file.getOriginalFilename());
            FileUtils.copyInputStreamToFile(inputStream, zipFile);

            // 解压缩文件
            String extractDir = System.getProperty("java.io.tmpdir") + File.separator + "student_photos";
            ZipFile zip = new ZipFile(zipFile);
            zip.extractAll(extractDir);

            // 检查解压目录是否存在
            File dir = new File(extractDir);
            if (!dir.exists() || !dir.isDirectory()) {
                return new ResultMsg(0, "解压缩失败或目录不存在。", null);
            }

            // 找到解压缩后的 Excel 文件
            File[] files = dir.listFiles((d, name) -> name.endsWith(".xlsx"));
            if (files == null || files.length == 0) {
                errorMessages.add("ZIP 文件中缺少 Excel 表格。");
                return new ResultMsg(0, "ZIP 文件中缺少 Excel 表格。", null);
            }
            File excelFile = files[0]; // 找到第一个以 .xlsx 结尾的文件

            // 读取 Excel 表格
            try (InputStream excelInputStream = new FileInputStream(excelFile)) {
                Workbook workbook = new XSSFWorkbook(excelInputStream);
                Sheet sheet = workbook.getSheetAt(0);

                for (int i = 1; i <= sheet.getLastRowNum(); i++) { // 从第1行开始，跳过表头
                    Row row = sheet.getRow(i);
                    if (row != null) {
                        String studentCode = row.getCell(0).getStringCellValue(); // 学号
                        String name = row.getCell(1).getStringCellValue();        // 姓名
                        String studentPicture = row.getCell(2).getStringCellValue();   // 照片名

                        // 检查照片是否存在
                        File photoFile = new File(extractDir + "/" + studentPicture);
                        if (!photoFile.exists()) {
                            errorMessages.add("第 " + (i + 1) + " 行照片 " + studentPicture + " 不存在！");
                            continue;
                        }

                        // 校验并保存学生信息与照片
                        String studentId = sysStudentDao.getStudentId(studentCode);
                        if (studentId == null) {
                            errorMessages.add("第 " + (i + 1) + " 行学生编号 " + studentCode + " 不存在！");
                            continue;
                        }
                        // 将 File 包装成 MultipartFile
                        try (FileInputStream photoInputStream = new FileInputStream(photoFile)) {
                            MultipartFile multipartFile = new MockMultipartFile(
                                    "file",
                                    photoFile.getName(),
                                    "image/jpeg",  // 根据实际文件类型设置
                                    photoInputStream
                            );
                            // 调用你的上传逻辑，更新学生照片
                            Map<String, Object> params = new HashMap<>();
                            params.put("studentId", studentId);
                            params.put("photo", studentPicture);

                            ResultMsg msg = this.uploadPhoto(params);
                            if (msg.getStatus() != 200) {
                                errorMessages.add("第 " + (i + 1) + " 行照片 " + studentPicture + " 上传失败！");
                            }
                        } catch (IOException e) {
                            errorMessages.add("第 " + (i + 1) + " 行照片 " + studentPicture + " 读取失败！");
                            e.printStackTrace();
                        }
                    }
                }
            }

            // 返回处理结果
            if (!errorMessages.isEmpty()) {
                return new ResultMsg(0, "部分数据有误，请检查并修改。", errorMessages);
            }

            return new ResultMsg(200, "照片上传并处理成功。", null);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultMsg(500, "文件上传失败。", null);
        }
    }

    @Override
    public ResultMsg uploadPhoto(Map<String, Object> map) {
        logger.info("uploadPhoto map{}",map);
        int count = sysStudentDao.uploadPhoto(map);
        ResultMsg msg;
        if (count>0){
            msg = new ResultMsg(200,"成功",null);
            return msg;
        }
        msg = new ResultMsg(500,"失败",null);
        return msg;
    }

}
